package forum.client;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.*;
import forum.shared.*;

public class LoginScreen extends Screen{

	private Label errorLbl;
	private DialogBox dialog;
	private TextBox username;
	private Label usernameLabel;
	private TextBox password;
	private Label passwordLabel;
	private Button login;
	private Button cancel;
	private FlexTable mainTable;
	private FlexTable buttonsTable;
	private VerticalPanel contentPanel;
	
	/**
	 * default constructor.
	 */
	public LoginScreen(){
		createComponents();
		setStyle();
		setTabOrder();
		setActions();
		setupScreenDisplay();
	}
	
	/**
	 * init all the components.
	 */
	protected void createComponents() {
		errorLbl = new Label();
		dialog = new DialogBox();
		username = new TextBox();
		usernameLabel = new Label("*Username:");
		password = new PasswordTextBox();
		passwordLabel = new Label("*Password:");
		login = new Button("Login");
		cancel = new Button("Cancel");
		mainTable = new FlexTable();
		buttonsTable = new FlexTable();
		contentPanel = new VerticalPanel();
	    // Move cursor focus to the input box.
	    username.setFocus(true);
	}
	
	/**
	 * setting the style to all the components.
	 */
	protected void setStyle() {
		errorLbl.addStyleName("errorLabel");
		dialog.addStyleName("dialogBoxHeader");
		mainTable.addStyleName("blueStyleTable");
		buttonsTable.addStyleName("buttonsTableCenter");
		contentPanel.addStyleName("dialogBox");
		mainTable.setSize("100%", "100%");
		
		int rows=2;
		for(int row=0;row<rows;row++){
			for(int col=0;col<=1;col++){
				mainTable.getCellFormatter().setStyleName(row, col, "blueStyleTd");
				if(col==0)
					mainTable.getCellFormatter().setHorizontalAlignment(row, col, HasAlignment.ALIGN_LEFT);
				else
					mainTable.getCellFormatter().setHorizontalAlignment(row, col, HasAlignment.ALIGN_CENTER);
			}
		}
		
		buttonsTable.getCellFormatter().setHorizontalAlignment(0, 0, HasAlignment.ALIGN_RIGHT);
		buttonsTable.getCellFormatter().setHorizontalAlignment(0, 1, HasAlignment.ALIGN_LEFT);
		
		//setting the style to the fields.
		username.addStyleName("fieldcell");
		password.addStyleName("fieldcell");
		
		//Setting the style to the labels.
		usernameLabel.addStyleName("labelcell");
		passwordLabel.addStyleName("labelcell");
		
		//setting the buttons style.
		login.addStyleName("button");
		cancel.addStyleName("button");
	}
	
	protected void setTabOrder(){
		username.setTabIndex(1);
		password.setTabIndex(2);
	}
	
	/**
	 * setting all the action for the buttons and mouse clicks.
	 */
	protected void setActions(){
	    // Listen for mouse events on the cancel button.
	    cancel.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				dialog.hide(true);
			}
		});
	    // Listen for mouse events on the login button.
	    login.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				login();
			}
		});
	    // Listen for keyboard events on the login button.
	    login.addKeyPressHandler(new KeyPressHandler() {
			@Override
			public void onKeyPress(KeyPressEvent event) {
				if (event.getCharCode() == KeyCodes.KEY_ENTER) {
					login();
			    }
			}
		});
	    // Listen for keyboard events on the password field.
	    password.addKeyPressHandler(new KeyPressHandler() {
			@Override
			public void onKeyPress(KeyPressEvent event) {
				if (event.getCharCode() == KeyCodes.KEY_ENTER) {
					login();
			    }
			}
		}); 
	    // Listen for keyboard events on the password field.
	    username.addKeyPressHandler(new KeyPressHandler() {
			@Override
			public void onKeyPress(KeyPressEvent event) {
				if (event.getCharCode() == KeyCodes.KEY_ENTER || event.getCharCode() == KeyCodes.KEY_TAB) {
					password.setFocus(true);
			    }
			}
		}); 
	}
	
	/**
	 * @return the data to send to the server.
	 */
	protected String getInput(){
		String usernameStr = username.getText();
		String passStr = password.getText();
		String error = "";
        if (usernameStr.isEmpty()) {
            error+="- please enter a username.\n";
        }
        if (passStr.isEmpty()) {
            error+="- Please enter a password\n";
        } 
        if (!error.equals("")) {
        	errorLbl.setText(error);
        	errorLbl.setVisible(true);
  	      	return null;
        }
        // if successful:
        return "Login" + Delimiters.MSG_PARTS + usernameStr + 
        	Delimiters.MSG_PARTS + passStr;
	}
	
	/**
	 * the function to do when registering.
	 */
	private void login(){
		login.setEnabled(false);
		ForumServiceAsync forumSvc = GWT.create(ForumService.class);
		// Set up the callback object.
	    AsyncCallback<ServerResponse> callback = new AsyncCallback<ServerResponse>() {
	    	public void onFailure(Throwable caught) {
	    		errorLbl.setText("Communication error. Please retry later.");
	    		errorLbl.setVisible(true);
	    		login.setEnabled(true);
	    	}
	    	//On successful communication.
			@Override
			public void onSuccess(ServerResponse response) {
				if (response!=null && response.hasExecuted()) {
					username.setText("");
					password.setText("");
	                int lastIndex = response.getResponse().length(); 
	                String permission = response.getResponse().substring(lastIndex-1);
	                int per = Integer.parseInt(permission);
	                if (per>0 && per<4) 
	                	SessionData.getInstance().setPermissions(UserPermissions.values()[per]);
	                else 
	                	SessionData.getInstance().setPermissions(UserPermissions.GUEST); //Guest
	                int start = response.getResponse().indexOf("\"");
	                int end = response.getResponse().lastIndexOf("\"");
	                SessionData.getInstance().setCurrentUser(response.getResponse().substring(start+1, end));
	                //Window.alert("-" + SessionData.getInstance().getCurrentUser() + "-");
					//Window.alert(response.getResponse());
					//login.setEnabled(true);
	                dialog.hide(true);
	                new MainScreen().setupDisplayInMainPanel();
	            } 
				else {
                	errorLbl.setText(response!=null ? 
                			response.getResponse() : "Unknown Error...");
                	errorLbl.setVisible(true);
                	login.setEnabled(true);
	            }
			}
	    };
		// Make the call to the forum service.
	    String input = getInput();
	    if(input == null){
	    	login.setEnabled(true);
	    	return;
	    }
	    forumSvc.sendMsg(input, callback);
	}
	
	/**
	 * composing the screen on top of the mainPanel which controls the body of the html.
	 */
	public void setupDisplayInMainPanel() {
//		Panel mainPanel = MainPanel.get();
//		mainPanel.clear();
//		mainPanel.add(contentPanel);
//		mainPanel.add(buttonsTable);
		
		dialog.center();
		username.setFocus(true);
	}
	
	/**
	 * setting up the display of this screen.
	 */
	protected void setupScreenDisplay(){
		contentPanel.add(mainTable);
		mainTable.setWidget(0, 0, usernameLabel);
		mainTable.setWidget(0, 1, username);
		mainTable.setWidget(1, 0, passwordLabel);
		mainTable.setWidget(1, 1, password);
		
		contentPanel.add(errorLbl);
		
		buttonsTable.setWidget(0, 0, login);
		buttonsTable.setWidget(0, 1, cancel);
		
		contentPanel.add(buttonsTable);
		dialog.setWidget(contentPanel);
		dialog.setText("BannanForum Login");
	}
}
